package cn.caplike.demo.spring.bean.lifecycle.service.impl;

import cn.caplike.demo.spring.bean.lifecycle.service.AccountService;
import org.springframework.beans.factory.InitializingBean;

import javax.annotation.PostConstruct;

/**
 * <dl>
 *     <dt>调用顺序:</dt>
 *     <dd>AccountService:: 静态代码块</dd>
 *     <dd>AccountService:: 代码块</dd>
 *     <dd>AccountService:: constructor called ...</dd>
 *     <dd>AccountService:: postConstruct</dd>
 *     <dd>InitializingBean:: afterPropertiesSet called ...</dd>
 *     <dd>name: null</dd>
 *     <dd>init-method called ...</dd>
 *     <dd>AccountService:: setName called ...</dd>
 *     <dd>AccountService:: saveAccount called ...</dd>
 *     <dd>AccountService:: 实例属性初始化</dd>
 * </dl>
 */
public class AccountServiceImpl implements AccountService, InitializingBean {

    private String name = initName();

    static {
        // ~ 1
        System.out.println("AccountService:: 静态代码块");
    }

    {
        // ~ 2
        System.out.println("AccountService:: 代码块");
    }

    private String initName() {
        System.err.println("AccountService:: 实例属性初始化");
        return "Cayo";
    }

    public AccountServiceImpl() {
        // ~ 3
        System.out.println("AccountService:: constructor called ...");
    }

//    @Bean
//    public Object obj() {
//        System.out.println("AccountService:: obj");
//        return new Object();
//    }

    /**
     * Description: {@code @PostConstruct} 依赖 xml 文件中配置: {@code <context:annotation-config/>}.
     */
    @PostConstruct
    public void postConstruct() {
        // ~ 4
        System.out.println("AccountService:: postConstruct");
    }

    /**
     * Description: 实现了 {@link InitializingBean} 接口.
     */
    @Override
    public void afterPropertiesSet() {
        // ~ 5
        System.out.println("InitializingBean:: afterPropertiesSet called ...");
        System.out.println("name: " + name);
    }

    /**
     * Description: 在 xml 中通过 init-method 指定.
     */
    public void init() {
        // ~ 6
        System.out.println("init-method called ...");
    }

    // =================================================================================================================

    /**
     * Description: 在 xml 中通过 destroy-method 指定.
     */
    public void destroy() {
        System.out.println("destroy-method called ...");
    }

    public void setName(String name) {
        System.out.println("AccountService:: setName called ...");
        this.name = name;
    }

    @Override
    public void saveAccount() {
        System.out.println("AccountService:: saveAccount called ...");
    }
}
